using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Publicuse.Util
{
  public class AesEncryptionUtil
  {
    private static string key = "v5z3de6nqRsZEKDTMAYjh7WgGmpul8tO";
    private static string iv = "RyglA9urswLtj2EfVo1NM3==";

    /// <summary>
    /// 获取密钥
    /// </summary>
    private static string Key
    {
      get { return @"bVYbTm70nTQPERc3"; }
    }

    /// <summary>
    /// 获取向量
    /// </summary>
    private static string IV
    {
      get { return @"grbTNDzaNEbV1Kqy"; }
    }

    /// <summary>
    ///  加密
    /// </summary>
    /// <param name="key">密钥</param>
    /// <param name="data">要被加密的明文</param>
    /// <returns>密文base64</returns>
    public static string Encrypt(string data)
    {
      if (!string.IsNullOrWhiteSpace(data))
      {
        byte[] encryData = Encoding.UTF8.GetBytes(data);
        Aes rijndaelCipher = Aes.Create();
        rijndaelCipher.Key = Convert.FromBase64String(key);
        rijndaelCipher.IV = Convert.FromBase64String(iv);
        rijndaelCipher.Mode = CipherMode.CBC;
        rijndaelCipher.Padding = PaddingMode.PKCS7;
        ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
        byte[] plainText = transform.TransformFinalBlock(encryData, 0, encryData.Length);
        string result = Convert.ToBase64String(plainText);
        return result;
      }
      else
      {
        return data;
      }
    }

    /// <summary>
    /// 解密
    /// </summary>
    /// <param name="key">密钥</param>
    /// <param name="encryptData">密文</param>
    /// <returns>明文</returns>
    public static string Decrypt(string data)
    {
      if (!string.IsNullOrWhiteSpace(data))
      {

        try
        {
          byte[] encryData = Convert.FromBase64String(data);
          Aes rijndaelCipher = Aes.Create();
          rijndaelCipher.Key = Convert.FromBase64String(key);
          rijndaelCipher.IV = Convert.FromBase64String(iv);
          rijndaelCipher.Mode = CipherMode.CBC;
          rijndaelCipher.Padding = PaddingMode.PKCS7;
          ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
          byte[] plainText = transform.TransformFinalBlock(encryData, 0, encryData.Length);
          string result = Encoding.UTF8.GetString(plainText);
          return result;
        }
        catch (Exception ex)
        {
          return data;
        }

      }
      else
      {
        return data;
      }
    }

    /// <summary>
    /// AES加密
    /// </summary>
    /// <param name="plainStr">明文字符串</param>
    /// <returns>密文</returns>
    public static string AESEncrypt(string plainStr)
    {
      byte[] bKey = Encoding.UTF8.GetBytes(Key);
      byte[] bIV = Encoding.UTF8.GetBytes(IV);
      byte[] byteArray = Encoding.UTF8.GetBytes(plainStr);

      string encrypt = null;
      using (Rijndael aes = Rijndael.Create())
      {
        using (MemoryStream mStream = new MemoryStream())
        {
          using (
            CryptoStream cStream = new CryptoStream(
              mStream,
              aes.CreateEncryptor(bKey, bIV),
              CryptoStreamMode.Write
            )
          )
          {
            cStream.Write(byteArray, 0, byteArray.Length);
            cStream.FlushFinalBlock();
            encrypt = Convert.ToBase64String(mStream.ToArray());
          }
        }
        aes.Clear();
      }
      return encrypt;
    }

    /// <summary>
    /// AES加密
    /// </summary>
    /// <param name="plainStr">明文字符串</param>
    /// <param name="returnNull">加密失败时是否返回 null，false 返回 String.Empty</param>
    /// <returns>密文</returns>
    public static string AESEncrypt(string plainStr, bool returnNull)
    {
      string encrypt = AESEncrypt(plainStr);
      return returnNull ? encrypt : (encrypt == null ? String.Empty : encrypt);
    }

    /// <summary>
    /// AES解密
    /// </summary>
    /// <param name="encryptStr">密文字符串</param>
    /// <returns>明文</returns>
    public static string AESDecrypt(string encryptStr, out string msg)
    {
      msg = string.Empty;
      try
      {
        byte[] bKey = Encoding.UTF8.GetBytes(Key);
        byte[] bIV = Encoding.UTF8.GetBytes(IV);
        byte[] byteArray = Convert.FromBase64String(encryptStr);

        string decrypt = null;
        using (Rijndael aes = Rijndael.Create())
        {
          using (MemoryStream mStream = new MemoryStream())
          {
            using (
              CryptoStream cStream = new CryptoStream(
                mStream,
                aes.CreateDecryptor(bKey, bIV),
                CryptoStreamMode.Write
              )
            )
            {
              cStream.Write(byteArray, 0, byteArray.Length);
              cStream.FlushFinalBlock();
              decrypt = Encoding.UTF8.GetString(mStream.ToArray());
            }
          }
          aes.Clear();
        }
        return decrypt;
      }
      catch (Exception ex)
      {
        msg = ex.Message;
        return String.Empty;
      }
    }

    /// <summary>
    /// AES解密
    /// </summary>
    /// <param name="encryptStr">密文字符串</param>
    /// <param name="returnNull">解密失败时是否返回 null，false 返回 String.Empty</param>
    /// <returns>明文</returns>
    public static string AESDecrypt(string encryptStr, bool returnNull)
    {
      string decrypt = AESDecrypt(encryptStr, out var msg);
      return returnNull ? decrypt : (decrypt == null ? String.Empty : decrypt);
    }
  }
}
